﻿using System;
using System.Text;
using System.IO;
using System.Collections.Specialized;
using System.Collections;

namespace Faml
{
    public class PrintHelper
    {
        public static void PrintValue(StringBuilder sb, object obj)
        {
            if (obj is OrderedDictionary)
            {
                OrderedDictionary od = obj as OrderedDictionary;
                sb.Append("{\n");
                int i = 0;
                foreach(DictionaryEntry entry in od)
                {
                    sb.AppendFormat("  {0} = ", entry.Key);
                    PrintValue(sb, entry.Value);
                    if (i++ < od.Count - 1)
                        sb.Append(",\n");
                }
                sb.Append("\n}");
            }
            else if (obj is Array)
                PrintArray(sb, (Array)obj);
            else
                sb.Append(obj);
        }

        public static void PrintArray(StringBuilder sb,Array array)
        {
            Array a = array;

            if (a.Rank == 1)
            {
                if (a.Length == 0)
                    sb.AppendLine("--empty--");
                else if (a.GetValue(0) is Array)
                {
                    for (int i = 0; i < a.Length; i++)
                        PrintArray(sb,a.GetValue(i) as Array);
                    sb.AppendLine();
                }
                else
                {
                    for (int i = 0; i < a.Length; i++)
                    {
                        PrintValue(sb, a.GetValue(i));
                        sb.Append(" ");
                    }
                    sb.AppendLine();
                }
            }
            else if (a.Rank == 2)
            {
                for (int i = 0; i < a.GetLength(0); i++)
                {
                    for (int j = 0; j < a.GetLength(1); j++)
                        sb.AppendFormat("{0} ", a.GetValue(i, j));
                    sb.AppendLine();
                }
            }
            else if (a.Rank == 3)
            {
                for (int i = 0; i < a.GetLength(0); i++)
                {
                    for (int j = 0; j < a.GetLength(1); j++)
                    {
                        for (int k = 0; k < a.GetLength(2); k++)
                        {
                            sb.AppendFormat("{0} ", a.GetValue(i, j, k));
                        }
                        sb.AppendLine();
                    }
                    sb.AppendLine();
                }
            }
        }

        // TODO: It is better to initially implement printing through
        // StreamWriter and then to StringBuilder
        public static void PrintArray(TextWriter sw, Array array)
        {
            StringBuilder sb = new StringBuilder();
            PrintArray(sb, array);
            sw.Write(sb.ToString());
        }

        public static void PrintArray(Array array)
        {
            PrintArray(Console.Out, array);
        }

        public static void Print(StringBuilder sb, object obj)
        {
            Array array = obj as Array;
            if (array != null)
                PrintArray(sb, array);
            else
                sb.AppendFormat("{0}\n", obj);
        }

        public static void Print(TextWriter sw, object obj)
        {
            Array array = obj as Array;
            if (array != null)
                PrintArray(sw, array);
            else
                sw.WriteLine("{0}", obj);
        }

        public static void Print(object obj)
        {
            Print(Console.Out, obj);
        }
    }
}